package cn.fan.testfunction.utils;

import cn.fan.testfunction.model.Constants;
import cn.fan.testfunction.model.JcjcDefectInfoDefectRectAttr;
import cn.hutool.core.date.DateUtil;

import org.apache.commons.lang3.RandomStringUtils;
import sun.misc.BASE64Decoder;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * @Description: 图片帮助类给图片标记红框
 */
public class ImageUtil {

    /**
     * 绘制图片所有标记的方框，并返回二进制流
     *
     *      read = ImageIO.read(inputStream);
     *                     if (Objects.isNull(read)) {
     *                         result=i18nConverter.getMessage("itps.yw.system.error.msg.pic.read.fail");
     *                         return result;
     *                     }
     *                     byte[] bytes = ImageUtil.DrawMarkImage(read, rectAttr, extension);
     */
    public static byte[] DrawMarkImage(BufferedImage bufferedImage, List<JcjcDefectInfoDefectRectAttr> defectRectList, String extension) {
        byte[] buffer = null;
        //处理灰化图片
        BufferedImage image = new BufferedImage(bufferedImage.getWidth(), bufferedImage.getHeight(), BufferedImage.TYPE_INT_RGB);

        //颜色不变
        Graphics2D g = image.createGraphics();
        g.drawImage(bufferedImage, 0, 0, null);
        g.dispose();

        //转换客户端标记的位置和大小
        List<JcjcDefectInfoDefectRectAttr> defectRects = getConvertDefectRect(bufferedImage, defectRectList);

        //绘制标记框
        if (image != null) {
            try {
                if (defectRects != null && defectRects.size() > 0) {
                    //Graphics2D对象相当于画笔
                    Graphics2D g2d = image.createGraphics();
                    // 设置线的型式
                    Stroke stroke = new BasicStroke(6.0f);
                    g2d.setStroke(stroke);
                    for (JcjcDefectInfoDefectRectAttr rect : defectRects) {
                        //红色
                        g2d.setColor(Color.RED);
                        //画一个矩形
                        RoundRectangle2D rRect = new RoundRectangle2D.Double(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight(), 0.0, 0.0);
                        g2d.draw(rRect);
                    }
                    //释放此图形的上下文并释放它所使用的所有系统资源
                    g2d.dispose();
                }
                ByteArrayOutputStream os = new ByteArrayOutputStream();
                ImageIO.write(image, extension, os);
                buffer = os.toByteArray();

            } catch (Exception ex) {

            }
        }

        return buffer;
    }


    /**
     * 转换客户端标记的位置和大小
     *
     * @param image
     * @param defectRects
     * @return
     */
    public static List<JcjcDefectInfoDefectRectAttr> getConvertDefectRect(BufferedImage image, List<JcjcDefectInfoDefectRectAttr> defectRects) {
        List<JcjcDefectInfoDefectRectAttr> result = new ArrayList<>();
        if (defectRects != null && defectRects.size() > 0) {
            //计算图片放大倍数
            double wFactor = image.getWidth() * 1.0 / defectRects.get(0).getPicWidth();
            double hFactor = image.getHeight() * 1.0 / defectRects.get(0).getPicHeight();

            //浏览器端的标记的边框大小决定 用于绘图补偿
            int clientMarkBorderWidth = 2;
            for (JcjcDefectInfoDefectRectAttr rect : defectRects) {

                //加上绘图补偿重置矩形高宽
                rect.setWidth(rect.getWidth() + clientMarkBorderWidth);
                rect.setHeight(rect.getHeight() + clientMarkBorderWidth);

                //新建真实比列矩形大小
                JcjcDefectInfoDefectRectAttr physicsDefectRect = new JcjcDefectInfoDefectRectAttr();
                physicsDefectRect.setPicWidth(image.getWidth());
                physicsDefectRect.setPicHeight(image.getHeight());
                physicsDefectRect.setX((int) (rect.getX() * wFactor));
                physicsDefectRect.setY((int) (rect.getY() * hFactor));
                physicsDefectRect.setWidth((int) (rect.getWidth() * wFactor));
                physicsDefectRect.setHeight((int) (rect.getHeight() * hFactor));

                //位置校正
                if (physicsDefectRect.getX() < 0) {
                    physicsDefectRect.setX(0);
                }
                if (physicsDefectRect.getY() < 0) {
                    physicsDefectRect.setY(0);
                }

                //高宽校正
                if (physicsDefectRect.getX() + physicsDefectRect.getWidth() > physicsDefectRect.getPicWidth()) {
                    physicsDefectRect.setWidth((int) physicsDefectRect.getPicWidth() - physicsDefectRect.getX() - clientMarkBorderWidth);
                }
                if (physicsDefectRect.getY() + physicsDefectRect.getHeight() > physicsDefectRect.getPicHeight()) {
                    physicsDefectRect.setHeight((int) physicsDefectRect.getPicHeight() - physicsDefectRect.getY() - clientMarkBorderWidth);
                }

                result.add(physicsDefectRect);
            }

        }
        return result;
    }

    /**
     * 将Base64图片转换成二进制流
     *
     * @param base64
     * @return
     */
    public static BufferedImage Base64ToByte(String base64) {
        BufferedImage bufferedImage = null;
        try {
            int location = base64.indexOf("base64,") + 7;
            base64 = base64.substring(location, base64.length());
            BASE64Decoder decoder = new BASE64Decoder();
            byte[] buffer = decoder.decodeBuffer(base64);
            if (buffer != null) {
                ByteArrayInputStream inputStream = new ByteArrayInputStream(buffer);
                bufferedImage = ImageIO.read(inputStream);
            }
        } catch (Exception ex) {
            bufferedImage = null;
        }
        return bufferedImage;
    }

    /**
     * 获取缺陷图片目录
     */
    public static String getDrawMarkImagePath() {
        return Constants.DEFECT_INFO_DRAW_MARK_IMAGE_ROOT_PATH + "/" + DateUtil.format(DateUtil.date(), "yyyyMM");
    }
    /**
     * 获取缺陷标记图片临时目录
     */
    public static String getDrawMarkTempImagePath() {
        return Constants.DEFECT_INFO_DRAW_MARK_TEMP_IMAGE_ROOT_PATH + "/" + DateUtil.format(DateUtil.date(), "yyyyMM");
    }
    /**
     * 获取缺陷图片名称
     * @return
     */
    public static String getDrawMarkImageName() {
        return DateUtil.current(false) + "_" + RandomStringUtils.random(5, true, true);
    }
}
